import fs from 'fs';
import path from 'path';

let SAMPLE_RATE = 16000;
let CHANNELS = 1;
let BIT_DEPTH = 16;
let OUTPUT_DIR = './temp_audio';

function createWavBufferFromPcm(pcmBuffer) {
  const dataLength = pcmBuffer.length;
  const fileLength = 36 + dataLength;
  const header = Buffer.alloc(44);

  header.write('RIFF', 0);
  header.writeUInt32LE(fileLength, 4);
  header.write('WAVE', 8);
  header.write('fmt ', 12);
  header.writeUInt32LE(16, 16);
  header.writeUInt16LE(1, 20);
  header.writeUInt16LE(CHANNELS, 22);
  header.writeUInt32LE(SAMPLE_RATE, 24);
  header.writeUInt32LE(SAMPLE_RATE * CHANNELS * (BIT_DEPTH / 8), 28);
  header.writeUInt16LE(CHANNELS * (BIT_DEPTH / 8), 32);
  header.writeUInt16LE(BIT_DEPTH, 34);
  header.write('data', 36);
  header.writeUInt32LE(dataLength, 40);

  return Buffer.concat([header, pcmBuffer]);
}

const queue = [];
let isWriting = false;
let shouldExit = false;

async function processQueue() {
  if (isWriting) return;
  isWriting = true;
  while (queue.length > 0) {
    const { pcm, name } = queue.shift();
    const filepath = path.join(OUTPUT_DIR, name);
    try {
      const wav = createWavBufferFromPcm(pcm);
      await fs.promises.writeFile(filepath, wav);
      // 写完一个，继续
    } catch (e) {
      process.send?.({ type: 'error', message: e?.message || String(e) });
    }
  }
  isWriting = false;
  if (shouldExit) {
    process.send?.({ type: 'exited' });
    process.exit(0);
  }
}

process.on('message', (msg) => {
  if (!msg || typeof msg !== 'object') return;
  if (msg.type === 'init') {
    const cfg = msg.config || {};
    SAMPLE_RATE = cfg.sampleRate || SAMPLE_RATE;
    CHANNELS = cfg.channels || CHANNELS;
    BIT_DEPTH = cfg.bitDepth || BIT_DEPTH;
    OUTPUT_DIR = cfg.outputDir || OUTPUT_DIR;
    if (!fs.existsSync(OUTPUT_DIR)) fs.mkdirSync(OUTPUT_DIR, { recursive: true });
    process.send?.({ type: 'ready' });
  } else if (msg.type === 'segment' && msg.pcm && msg.name) {
    // 注意：通过 IPC 发送的 Buffer 会被序列化；在 ESM 下仍可作为 Buffer 接收
    const pcm = Buffer.isBuffer(msg.pcm) ? msg.pcm : Buffer.from(msg.pcm.data || msg.pcm);
    queue.push({ pcm, name: msg.name });
    processQueue();
  } else if (msg.type === 'exit') {
    shouldExit = true;
    if (!isWriting && queue.length === 0) {
      process.send?.({ type: 'exited' });
      process.exit(0);
    }
  }
});

process.send?.({ type: 'ready' });

process.on('SIGINT', () => {
  shouldExit = true;
  if (!isWriting && queue.length === 0) {
    process.send?.({ type: 'exited' });
    process.exit(0);
  }
});


